Extend the auth-attempt contract for credential refresh - #78
Merged
Conversation
Extends the authentication attempt contract for in-app credential refresh (e.g. expired AWS SSO / Google ADC sessions): - New 'external-browser' challenge kind for flows where an external process (spawned CLI) owns the browser; carries attemptId, expiresIn, instructions, and an optional url. - New 'unavailable' AuthenticationStartResult variant meaning no attempt was created (required CLI missing, no SSO profile, etc.) so callers can fall back to a configuration UI instead of catching a throw. Duplicate-start ownership (already-in-progress) and disposal-cancel semantics are unchanged; the new variants are purely additive.
A silent (browser-free) token refresh finishes inside startAuthentication — no attempt is created, nothing is polled or cancelled — so the attempt contract needs a way to say 'already done; refetch status and models'. The interactive paths are unchanged and still ride attempts end to end.
These tests constructed typed literals and asserted the same literals back, so they could not detect a behavioral regression — TypeScript already supplies their only useful coverage. The protocol handler and standalone tests cover the real pass-through and rendering behavior.
Hosts with a graphical configuration overlay rewrite the credential-expiry toast to a Reconnect action that opens the overlay and starts an in-app credential refresh. The bridge keeps emitting REFRESH_MODELS with CLI copy as its host-agnostic default; the rewrite happens in the Node provider callbacks when the host opts in.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consumers that refresh expired credentials (for example AWS SSO or Google ADC) can't express two common outcomes with the current attempt contract: a refresh that finishes synchronously with no user interaction, and a refresh that can't be attempted at all in the current environment. They also can't represent a login flow whose browser step is owned by an external process like a spawned CLI. Callers have to fake these cases with errors or side channels.
This PR extends the authentication contract in
ai-credentialswith three additions. A newexternal-browserchallenge kind describes a flow where an external process (such asgcloud) owns the browser step, with display instructions and an optional URL. Acompletedstart result covers synchronous refreshes — such as a silent token refresh — that create no attempt and just tell the caller to refetch auth status. Anunavailablestart result with a reason covers cases where no attempt can be created (missing CLI, no SSO profile, no reachable browser), so the caller can fall back to a configuration UI.All additions are new union members, so existing consumers compile and behave unchanged. The new contract is covered by attempt-contract tests.
Changes
AuthenticationChallengegains anexternal-browserkind for flows where a spawned process owns the browser step. Previously, only interactive URL-based challenges could be expressed.AuthenticationStartResultgainscompletedandunavailablestatuses. Previously, a start call could only reportstartedoralready-in-progress, leaving no way to express synchronous success or environment-level unavailability.